/**
 * MainWindow.java 2008-05-16
 * 
 * Linker is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

package linker.gui;

import linker.LocalVariablesManager;
import linker.account.ManageAccount;
import linker.list.ViewList;
import linker.plugin.PluginWindow;
import linker.status.StatusIcons;
import linker.status.StatusManager;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

import org.jivesoftware.smack.packet.Presence;

/**
 * The main window. It contains the viewed lists,and the menubar you can use to
 * configure the software.
 * 
 * We've tried to make it easier to release a version for Simplified Chinese
 * user
 * 
 * @version 2008-05-28
 * @author Jianfeng tujf.cn@gmail.com
 * @author AwakenRz awakenrz@gmail.com
 * @author Tan tan1986@gmail.com
 * 
 */

public class MainWindow extends JFrame implements ActionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * The list used to show buddy,message,plugin.
	 */
	private ViewList list;

	/**
	 * The information to display for input status.
	 */
	private final String statusInputLabel = LocalVariablesManager
			.getLocalVariables("MainWindow.StatusTextField");

	/**
	 * The Label to display the number of message list.
	 */
	private JLabel listLabel;

	/**
	 * The label to display the current status.
	 */
	private JLabel statusLabel;

	/**
	 * The default length of JTextField.
	 */
	private final int jTextFieldLength = 10;

	/**
	 * The field used for user to input status.
	 */
	private JTextField statusField = new JTextField(jTextFieldLength);

	/**
	 * The trayicon on the desktop.
	 */
	private TrayIcon trayIcon;

	/**
	 * The popupMenu of the trayicon.
	 */
	private TrayIconPopup trayPopup;

	/**
	 * The userPanel.
	 */
	private JPanel userPanel;

	/**
	 * The label for display the current status,include status Icon.
	 */
	private JLabel statusBox;

	/**
	 * The field used to filter the current items in the list.
	 */
	private FilterField searchField;

	/**
	 * The path of "resources/images".
	 */
	private String imageDirPath;

	/**
	 * The menu used for user to change status.
	 */
	private JPopupMenu statusMenu;

	/**
	 * Unread label 2 ie."message".
	 */
	private final String unreadLabel1 = LocalVariablesManager
			.getLocalVariables("MainWindow.UnreadMessageLabel1");

	/**
	 * 
	 */
	private final String unreadLabel2 = LocalVariablesManager
			.getLocalVariables("MainWindow.UnreadMessageLabel2");

	/**
	 * Unread label 3 ie."messages".
	 */
	private final String unreadLabel3 = LocalVariablesManager
			.getLocalVariables("MainWindow.UnreadMessageLabel3");

	/**
	 * 
	 */
	private MouseAdapter mouseAdapter = new MouseAdapter() {
		public void mouseClicked(final MouseEvent e) {

			if (e.getSource() == listLabel) {
				list.changeList();
			} else if (e.getSource() == statusLabel) {

				if (!statusLabel.getText().equals(statusInputLabel)) {
					statusField.setText(statusLabel.getText());
				} else {
					statusField.setText("");
				}

				userPanel.add(statusField, BorderLayout.CENTER);
				userPanel.remove(statusLabel);
				userPanel.updateUI();

				statusField.requestFocus();
				statusField.selectAll();
			}

		}
	};

	/**
	 * The constructor.
	 * 
	 * @param viewList
	 *            The list show the buddies, messages, plugins.
	 */
	public MainWindow(final ViewList viewList) {
		super(LocalVariablesManager.getLocalVariables("MainWindow"));
		setName("MainWindow");
		setIconImage(ManageAccount.getLogo());
		this.list = viewList;
		imageDirPath = ManageAccount.getImagePath();

		Container container = getContentPane();

		// Create menubar.
		JMenuBar menubar = createMenuBar();
		setJMenuBar(menubar);

		// Status Menu
		statusMenu = new JPopupMenu();
		JMenuItem statusItem = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.StatusMenu.Online"));
		statusItem.setIcon(StatusIcons.getFreeIcon());
		statusItem.addActionListener(this);
		statusMenu.add(statusItem);
		statusItem = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.StatusMenu.Busy"));
		statusItem.setIcon(StatusIcons.getBusyIcon());
		statusItem.addActionListener(this);
		statusMenu.add(statusItem);
		statusItem = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.StatusMenu.Away"));
		statusItem.setIcon(StatusIcons.getAwayIcon());
		statusItem.addActionListener(this);
		statusMenu.add(statusItem);

		// User panel
		userPanel = new JPanel();
		userPanel.setLayout(new BorderLayout());
		statusBox = new JLabel();
		statusBox.setIcon(StatusIcons.getFreeIcon());
		statusBox.setComponentPopupMenu(statusMenu);
		userPanel.add(statusBox, BorderLayout.WEST);
		statusLabel = new JLabel(statusInputLabel);
		statusLabel.addMouseListener(mouseAdapter);
		statusField.addActionListener(this);
		statusField.addFocusListener(new FocusAdapter() {
			public void focusLost(final FocusEvent e) {

				if (statusField.getText().trim().length() == 0) {
					statusLabel.setText(statusInputLabel);
				} else {
					StatusManager.getManager(null).setStatus(null,
							statusField.getText());
				}

				userPanel.add(statusLabel, BorderLayout.CENTER);
				userPanel.remove(statusField);
				userPanel.updateUI();
			}
		});
		userPanel.add(statusLabel, BorderLayout.CENTER);
		container.add(userPanel, BorderLayout.NORTH);

		JPanel centerPanel = new JPanel();
		centerPanel.setLayout(new BorderLayout());

		JScrollPane pane = new JScrollPane(viewList);
		int horizontal = JScrollPane.HORIZONTAL_SCROLLBAR_NEVER;
		pane.setHorizontalScrollBarPolicy(horizontal);
		centerPanel.add(pane, BorderLayout.CENTER);

		// Search field
		final int filterFieldLength = 10;
		searchField = new FilterField(filterFieldLength, viewList);
		searchField.addActionListener(this);
		centerPanel.add(searchField, BorderLayout.NORTH);
		container.add(centerPanel, BorderLayout.CENTER);

		// Status label
		listLabel = new JLabel(LocalVariablesManager
				.getLocalVariables("MainWindow.UnreadMessageLabel1")
				+ 0
				+ " "
				+ LocalVariablesManager
						.getLocalVariables("MainWindow.UnreadMessageLabel3"));
		listLabel.addMouseListener(mouseAdapter);
		container.add(listLabel, BorderLayout.SOUTH);

		// Add close window listener and initial trayicon.
		trayPopup = new TrayIconPopup(this);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(final WindowEvent e) {
				if (SystemTray.isSupported()) {

					setVisible(false);
					trayPopup.setShowCheckBox(false);
				} else {
					System.exit(0);
				}
			}
		});

		if (SystemTray.isSupported()) {
			initialTrayIcon();
		}

		// Set size and location.
		pack();
		setLocationRelativeTo(null);
		try {
			WindowSaver.loadSettings(this);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the mainWindow use menuBar.
	 * 
	 * @return Menu bar.
	 */
	private JMenuBar createMenuBar() {
		// Menu bar
		JMenuBar menubar = new JMenuBar();
		// Seting menu.
		JMenu menu = new JMenu(LocalVariablesManager
				.getLocalVariables("MainWindow.SettingMenu"));
		JMenuItem item = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.SettingMenu.Plugins"));
		item.addActionListener(this);
		menu.add(item);
		item = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.SettingMenu.Settings"));
		item.addActionListener(this);
		menu.add(item);
		menubar.add(menu);

		// View menu.
		menu = new JMenu(LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu"));
		String onlineBuddyOnly = LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu.OnlineBuddyOnly");
		final JCheckBoxMenuItem checkbox = new JCheckBoxMenuItem(
				onlineBuddyOnly);
		checkbox.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				if (checkbox.isSelected()) {
					list.setOnlineOnly(true);
				} else {
					list.setOnlineOnly(false);
				}
			}
		});
		menu.add(checkbox);
		menu.add(new JSeparator());

		// Select list.
		item = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu.BuddyList"));
		item.addActionListener(this);
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B,
				ActionEvent.ALT_MASK));
		menu.add(item);

		item = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu.MessageList"));
		item.addActionListener(this);
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M,
				ActionEvent.ALT_MASK));
		menu.add(item);

		item = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu.PluginList"));
		item.addActionListener(this);
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,
				ActionEvent.ALT_MASK));
		menu.add(item);
		menubar.add(menu);

		// About menu.
		menu = new JMenu(LocalVariablesManager
				.getLocalVariables("MainWindow.AboutMenu"));
		item = new JMenuItem(LocalVariablesManager
				.getLocalVariables("MainWindow.AboutMenu.About"));
		item.addActionListener(this);
		menu.add(item);
		menubar.add(menu);

		return menubar;
	}

	/**
	 * Intiral trayIcon.
	 */
	private void initialTrayIcon() {
		Image image = Toolkit.getDefaultToolkit().createImage(
				imageDirPath + "logo0.png");

		trayIcon = new TrayIcon(image, "Linker", trayPopup);
		trayIcon.addMouseListener(TrayIconListener.getTrayIconListener(this,
				trayPopup));

		try {
			trayIcon.setImageAutoSize(true);
			SystemTray.getSystemTray().add(trayIcon);
		} catch (AWTException e) {
			e.printStackTrace();
		}
	}

	/**
	 * change status.
	 * 
	 * @param e
	 *            ActionEvent
	 */
	public final void actionPerformed(final ActionEvent e) {

		if (e.getActionCommand() == LocalVariablesManager
				.getLocalVariables("MainWindow.AboutMenu.About")) {
			// About window
			new AboutWindow();
		} else if (e.getSource() == statusField) {
			// Status field
			statusLabel.setText(statusField.getText());
			userPanel.remove(statusField);
			userPanel.add(statusLabel, BorderLayout.CENTER);
			userPanel.updateUI();
		} else if (e.getActionCommand() == LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu.MessageList")) {

			// change to message list
			list.setListModelByName(ViewList.LISTNAME.MESSAGELIST);
		} else if (e.getActionCommand() == LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu.BuddyList")) {

			// change to buddy list
			list.setListModelByName(ViewList.LISTNAME.BUDDYLIST);
		} else if (e.getActionCommand() == LocalVariablesManager
				.getLocalVariables("MainWindow.ViewMenu.PluginList")) {

			// change to function list
			list.setListModelByName(ViewList.LISTNAME.PLUGINLIST);
		} else if (e.getActionCommand() == LocalVariablesManager
				.getLocalVariables("MainWindow.SettingMenu.Plugins")) {

			// Plugins Window.
			PluginWindow.getPluginManager().setVisible(true);
		} else if (e.getActionCommand() == LocalVariablesManager
				.getLocalVariables("MainWindow.SettingMenu.Settings")) {

			// Settings Window.
			SettingsWindow window = SettingsWindow.getSettingWindow();
			window.pack();
			window.setVisible(true);
		} else if (e.getSource() == searchField) {

			// Add element to this function.
			list.addElement(searchField.getText());
		} else {
			// Get from status label
			String status = "";
			if (!statusLabel.getText().equals(this.statusInputLabel)) {
				status = statusLabel.getText();
			}

			if (e.getActionCommand() == LocalVariablesManager
					.getLocalVariables("MainWindow.StatusMenu.Online")) {

				StatusManager.getManager(null).setStatus(
						Presence.Mode.available, status);
			} else if (e.getActionCommand() == LocalVariablesManager
					.getLocalVariables("MainWindow.StatusMenu.Busy")) {

				StatusManager.getManager(null).setStatus(Presence.Mode.dnd,
						status);

			} else if (e.getActionCommand() == LocalVariablesManager
					.getLocalVariables("MainWindow.StatusMenu.Away")) {

				StatusManager.getManager(null).setStatus(Presence.Mode.away,
						status);

			}
		}
	}

	/**
	 * Set status info, include statusInfo and icon.
	 * 
	 * @param status
	 *            Status info
	 * @param icon
	 *            Icon for status
	 */
	public final void setStatus(final String status, final ImageIcon icon) {
		if (status != null) {
			statusLabel.setText(status);
		}

		statusBox.setIcon(icon);
	}

	/**
	 * Set statusLabel to display how many messages .
	 * 
	 * @param n
	 *            The number of messages.
	 */
	public final void setStatusLabel(final int n) {
		String imagePath;

		StringBuffer buffer = new StringBuffer(unreadLabel1);
		buffer.append(n).append(" ");
		if (n > 1) {
			buffer.append(unreadLabel2);
		} else {
			buffer.append(unreadLabel3);
		}
		listLabel.setText(buffer.toString());

		final int logoNumber = 4;
		if (n < logoNumber) {
			imagePath = imageDirPath + "logo" + n + ".png";
		} else {
			imagePath = imageDirPath + "logo4.png";
		}

		if (trayIcon != null) {
			trayIcon.setImage(Toolkit.getDefaultToolkit()
					.createImage(imagePath));
		}
	}
}
